
partita* nuova_partita() {
	partita *game = malloc(sizeof(partita));
	assert(game != NULL);
	game->era = 1;
	game->turno = 1;
	inizializza_giocatori(game);
	game->scarti = NULL;
	azzera_tabella_punti(game);
	
	inizializza_era1(game);
	return game;
}

void azzera_tabella_punti(partita* game){
	int i, j;
	for(i = 0; i < 7; i++){
		for(j = 0; j < 8; j++){
			game->tabella_punti[i][j] = 0;
		}
	}
	return;
}

void inizializza_era1(partita *game) {
	int i;
	carta *mazzo = mazzo_era1();
	mazzo = mescola_mazzo(mazzo);
	for(i = 0; i < 7; i++) {
		game->giocatori[i].mano = pesca7(&mazzo);
	}
	return;
}

void inizializza_era2(partita *game) {
	int i;
	carta *mazzo = mazzo_era2();
	mazzo = mescola_mazzo(mazzo);
	for(i = 0; i < 7; i++) {
		game->giocatori[i].mano = pesca7(&mazzo);
	}
	return;
}

void inizializza_era3(partita *game) {
	int i;
	carta *mazzo = mazzo_era3();
	mazzo = mescola_mazzo(mazzo);
	for(i = 0; i < 7; i++) {
		game->giocatori[i].mano = pesca7(&mazzo);
	}
	return;
}

void esegui_turno(partita *game) {
	int i, j, k;
	carta *carta_giocata[7];
	Modo_gioca_carta modo_di_giocare;
	modi *modi_di_comprare = NULL;
	int scelta;
	carta *curr_carta;
	modi *curr_modo;
	modi* modo_gioca[7];
	   
	// Decidi la carta da giocare e il modo in cui giocarla e comprarla
	for (i = 0; i < 7; i++) {
		scegli_carta:
		printf("Giocatore %d, le tue carte sono:\n", i+1);
		k = 0;
		curr_carta = game->giocatori[i].mano;
		while (curr_carta != NULL) {
			k++;
			printf("%2d) Carta #%d %s\n", k, curr_carta->num, curr_carta->nome);
			curr_carta = curr_carta->succ;
		}
		   
		do {
			printf("Inserisci il numero della carta da giocare [1-%d]:\n", k);
			scelta = leggi_intero();
		} while (scelta <= 0 || scelta > k);
		   
		carta_giocata[i] = game->giocatori[i].mano;
		for (j = 1; j < scelta; j++) carta_giocata[i] = carta_giocata[i]->succ;
		   
		// chiede come usarla
		scegli_modo_giocare:
		do {
			printf("Cosa vuoi farci con la carta scelta?\n 1) Gioca\n 2) Meraviglia\n 3) Vendi\n 4) Annulla\n");
			scelta = leggi_intero();
		} while (scelta < 1 || scelta > 4);
		if (scelta == 4) goto scegli_carta;
		   
		modo_di_giocare = (Modo_gioca_carta)(scelta - 1);
		dealloca_modi(modi_di_comprare); // serve perchè usiamo i goto
		modi_di_comprare = calcola_modi_di_comprare(game, i, carta_giocata[i], modo_di_giocare);
		   
		// calcola o chiedi quale dei modi di comprare
		if (modi_di_comprare == NULL) {
			printf("Non puoi giocare questa carta in questo modo\n");
			goto scegli_modo_giocare;
		}
		   
		if (modi_di_comprare->succ == NULL) {
			// puoi giocarla in un solo modo
			modo_gioca[i] = modi_di_comprare;
			modi_di_comprare = NULL;
		} else {
			modo_gioca[i] = modi_cerca_gratis(modi_di_comprare);
			if (modo_gioca[i] != NULL) {
				// puoi giocarla senza spendere monete
			} else {
				// tante possibilità
				printf("Come vuoi effettuare l'acquisto?\n");
				k = 0;
				curr_modo = modi_di_comprare;
				while (curr_modo != NULL) {
					k++;
					printf("%2d) ", k);
					int primo = 1;
					if (curr_modo->paga.sinistra > 0) {
						if (!primo) printf(" \t");
						primo = 0;
						printf("Paga %d monete a sinistra", curr_modo->paga.sinistra);
					}
					if (curr_modo->paga.destra > 0) {
						if (!primo) printf(" \t");
						primo = 0;
						printf("Paga %d monete a destra", curr_modo->paga.destra);
					}
					if (curr_modo->paga.banco > 0) {
						if (!primo) printf(" \t");
						primo = 0;
						printf("Paga %d monete al banco", curr_modo->paga.banco);
					}
					printf("\n");
					curr_modo = curr_modo->succ;
				}
				   
				do {
					printf("Inserisci il numero del modo [0 per annullare]:\n");
					scelta = leggi_intero();
				} while (scelta < 0 || scelta > k);
				if (scelta == 0) goto scegli_modo_giocare;
				
				modo_gioca[i] = modi_di_comprare;
				for (j = 1; j < scelta; j++) modo_gioca[i] = modo_gioca[i]->succ;
			}
			
			// TODO: chiedi conferma
			
			modi_di_comprare = modi_togli(modi_di_comprare, modo_gioca[i]);
		}
		dealloca_modi(modi_di_comprare);
		modi_di_comprare = NULL;
	}
		   
	// Gioca le carte come deciso
	for (i = 0; i < 7; i++) {
		game->giocatori[i].mano = lista_carte_togli(game->giocatori[i].mano, carta_giocata[i]);
		gioca_carta(game, &game->giocatori[i], carta_giocata[i], modo_gioca[i]);
		dealloca_modi(modo_gioca[i]);
	}
	//ruota le mani dei giocatori
	ruota_mani_giocatori(game);
	return;
}

void applica_guerre(partita* game){
	int i;
	int era = game->era;
	int guadagno_guerra;
	
	switch(era){
		case 1:
			guadagno_guerra = 1;
			break;
		case 2:
			guadagno_guerra = 3;
			break;
		case 3:
			guadagno_guerra = 5;
			break;
		default:
			return;
	}
	
	for(i = 0; i < 7; i++){
		//a sinistra
		if(game->giocatori[i].scudi > game->giocatori[i].sinistra->scudi){
			game->giocatori[i].guerra.sinistra[era] += guadagno_guerra;
		}
		else if(game->giocatori[i].scudi < game->giocatori[i].sinistra->scudi){
			game->giocatori[i].guerra.sinistra[era] = -1;
		}
		//a destra
		if(game->giocatori[i].scudi > game->giocatori[i].destra->scudi){
			game->giocatori[i].guerra.destra[era] += guadagno_guerra;
		}
		else if(game->giocatori[i].scudi < game->giocatori[i].destra->scudi){
			game->giocatori[i].guerra.destra[era] = -1;
		}
	}
	return;
}

void dealloca_tutto(partita* game){
	int i;
	for(i = 0; i < 7; i++){
		dealloca_meraviglia(game->giocatori[i].meraviglia);
	}
	free(game);
	return;
}

void ruota_mani_giocatori(partita* game){
	carta* temp = game->giocatori[0].mano;
	int i;
	for(i = 0; i < 6; ++i){
		game->giocatori[i].mano = game->giocatori[i+1].mano;
	}
	game->giocatori[6].mano = temp;
	return;
}

void svuota_mani(partita *game){
	int i;
	for(i = 0; i < 7; i++){
		game->scarti = lista_carte_aggiungi(game->scarti, game->giocatori[i].mano);
		game->giocatori[i].mano = NULL;
	}
	return;
}

void stampa_tutto(partita *game, int turno){
	printf("--------------------- TURNO %d ---------------------\n", turno);
	int i;
	for(i = 0; i < 7; i++){
		printf("\n\tGIOCATORE %d [monete: %d]:\nMeraviglia (liv %d) ", i + 1, game->giocatori[i].soldi, game->giocatori[i].meraviglia->livello);
		stampa_nome_mera(i);
		printf("\tCarte in mano: # ");
		stampa(game->giocatori[i].mano);
		printf("\nCAMPO\nRisorse:\t#");
		stampa(game->giocatori[i].risorse_campo);
		printf("\nStrutture:\t#");
		stampa(game->giocatori[i].strutture_campo);
		printf("\nScarti meraviglia:\t#");
		stampa(game->giocatori[i].scarti_meraviglia);
	}
	printf("\n\nScarti:\t");
	stampa(game->scarti);
	printf("\n\n");
	return;
}

void stampa_separatore_ere(int era){
	printf("------------------------------------------------------------------------------------------------\n----------------------------------------FINE ERA %d----------------------------------------------\n------------------------------------------------------------------------------------------------\n\n", era);
}

void stampa_risultati(int tabella_punti[7][8]){
	int i;
	printf("\t\tGiocatore 1\tGiocatore 2\tGiocatore 3\tGiocatore 4\tGiocatore 5\tGiocatore 6\tGiocatore 7\n");
	printf("_____________________________________________________________________________________________________________________________\n");
	
	printf("\nRosso\t\t\t");
	for(i = 0; i < 7; i++){
		printf("%d\t\t", tabella_punti[i][0]);
	}
	
	printf("\nSoldi\t\t\t");
	for(i = 0; i < 7; i++){
		printf("%d\t\t", tabella_punti[i][1]);
	}
	
	printf("\nMeraviglia\t\t");
	for(i = 0; i < 7; i++){
		printf("%d\t\t", tabella_punti[i][2]);
	}
	
	printf("\nBlu\t\t\t");
	for(i = 0; i < 7; i++){
		printf("%d\t\t", tabella_punti[i][3]);
	}
	
	printf("\nGiallo\t\t\t");
	for(i = 0; i < 7; i++){
		printf("%d\t\t", tabella_punti[i][4]);
	}
	
	printf("\nViola\t\t\t");
	for(i = 0; i < 7; i++){
		printf("%d\t\t", tabella_punti[i][5]);
	}
	
	printf("\nVerde\t\t\t");
	for(i = 0; i < 7; i++){
		printf("%d\t\t", tabella_punti[i][6]);
	}
	
	printf("\n_____________________________________________________________________________________________________________________________\n\nTotale\t\t\t");
	for(i = 0; i < 7; i++){
		printf("%d\t\t", tabella_punti[i][7]);
	}
	printf("\n_____________________________________________________________________________________________________________________________\n");

	return;
}
